home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
dskut
/
comp_pv.zip
/
COMP.A86
next >
Wrap
Text File
|
1989-08-05
|
11KB
|
605 lines
; COMP Replacement for the messy-dos command of the same name.
; Usage: comp [/#] file1 [file2]
; where file1 and file2 may be directories or may contain
; wildcards (but not both). The default for file2 is the current
; directory on the current disk. The switch gives the maximum
; number of errors to report per file. Default is 65535 if file1
; refers to a single file, 10 otherwise.
; The '/' in the switch refers to the switch character.
; Author: Paul Vojta
stdout equ 1
stderr equ 2
CR equ 13
LF equ 10
TAB equ 9
fn1 equ word [5ch] ;filename portion of string 1
str2 equ word [5eh] ;string 2
fn2 equ word [60h]
pat2 equ 62h ;pattern for filling in wild cards in filename 2
str1 equ 70h
attr equ 21 ;byte in area43 (see below)
flname equ 30 ;ditto
; Begin. Set disk transfer address and slash.
mov dx,offset area43
mov ah,1ah
int 21h
mov ax,3700h
int 21h
cmp dl,'/'
jne f1
mov byte slash,'\'
f1: cld
; Compute buffer size.
mov ax,sp
sub ax,offset buf+100h
shr ax,1
mov al,0
mov word buflen,ax
; Start scanning parameters.
mov si,81h
f2: lodsb ;skip spaces
cmp al,' '
je f2 ;if space
cmp al,TAB
je f2 ;if tab
cmp al,dl
jne f7 ;if not switch
xor bx,bx ;value of parameter
mov cx,10
f3: lodsb
sub al,'0'
jb f4 ;if not digit
cmp al,9
ja f4 ;ditto
xchg ax,bx
mul cx
mov bh,0
add bx,ax
jmp f3
f4: mov maxerrs,bx ;save argument
inc si ;counteract later `dec'
cmp al,' '-'0'
je f7 ;if ended with space
cmp al,TAB-'0'
je f7 ;if ended with tab
mov dx,offset msg1 ;illegal switch
cmp al,CR-'0'
jne f6 ;error quit
f5: mov dx,offset msg2 ;insufficient parameters
f6: jmp errend
f7: dec si ;get first parameter
mov di,str1
call getparm
jz f5 ;if no parameter present
pushf
push area43+attr
mov fn1,bx ;beginning of file name 1
lea di,[bx+14]
mov str2,di ;start of second string
call getparm
mov fn2,bx
mov si,bx ;set up pat2
mov di,pat2
mov cx,7
rep movsw
pop area43+attr
popf
jns f9 ;if wild cards
cmp word maxerrs,0
jnz f8 ;if maxerrs given
mov word maxerrs,-1 ;default = -1
mov byte hyph,0 ;don't print hyphens
f8: call doit
jmp short quit
; Compare multiple files.
f9: cmp word maxerrs,0
jnz f10 ;if maxerrs given
mov word maxerrs,10 ;default = 10
f10: mov dx,str1
mov cx,1
mov ah,4eh ;find first file
int 21h
jc f12 ;if not found
mov word okmsg,offset crlf
f11: mov si,offset area43+flname
mov di,fn1
mov cx,7
rep movsw
mov dx,str1
call print
call doit
mov ah,4fh ;find next file
int 21h
jnc f11
quit: mov ax,4c00h
int 21h
f12: mov dx,offset msg3 ;file not found
jmp errend
; GETPARM Get next parameter. Upon entry, si points to the next character
; in the command string and di points where to put it. On exit,
; si points to the next+1 character in the command line, di points
; to the end of the parameter, and bx points to the beginning of
; the filename part of the string. AH=0 if no parameter, 1 if
; wild cards are present, and 80h if it is a file. Flags are set
; according to AH.
getparm:mov str2,di
gp0: lodsb ;skip separators
cmp al,' '
je getparm
cmp al,TAB
je getparm
cmp al,CR
mov ah,0
je gp8 ;if C/R
gp1: stosb ;copy until separator
lodsb
cmp al,' ' ;check for separator
je gp2
cmp al,TAB
je gp2
cmp al,CR
jne gp1
dec si
; Process the parameter.
gp2: mov byte [di],0
mov bx,di
mov ah,81h ;scan for start of file name
gp3: dec bx
cmp bx,str2
jl gp5 ;if past beginning
mov al,[bx]
cmp al,slash
je gp6 ;if '\' or '/'
cmp al,'?' ;check for wild cards
je gp4
cmp al,'*'
jne gp3
gp4: and ah,7fh ;clear no-wild bit
jmp gp3
gp5: cmp byte [bx+2],':' ;no dir. given; remove drive letter
jne gp6
inc bx
inc bx
gp6: inc bx
or ah,ah
jns gp9 ;if wild cards
cmp bx,di
mov ah,1
je gp8 ;if no file name
mov ax,4300h ;see if directory
mov dx,str2
int 21h
mov ah,80h
jc gp9 ;if not found
test cl,10h ;test attribute for directory
jz gp9 ;if file
; It's a directory.
mov al,slash
stosb
mov ah,1
gp8: push ax
mov bx,di ;add "*.*"
mov ax,'.*'
stosw
stosb
mov byte [di],0
pop ax
; Return.
gp9: or ah,ah ;set flags
ret
; DOIT Do it. Str1, str2, and pat2 are assumed to be set up.
doit: mov si,pat2
mov bx,fn1
mov di,fn2
mov cx,8
call dopart ;translate wild cards for main part of file name
dec si
d1: lodsb ;skip to file extension
or al,al
jz d3 ;if end of file
cmp al,'.'
jne d1
stosb ;store '.'
d2: mov al,byte [bx] ;skip to extension in first file name
cmp al,0
jz d2a
inc bx
cmp al,'.'
jne d2
d2a: mov cl,3 ;translate wild cards for file extension
call dopart
; Set up files.
d3: mov byte [di],0 ;store terminating zero
mov dx,str1 ;open file
mov ax,3d00h
int 21h
if c jmp err ;if error
mov si,ax
mov ax,3d00h ;open file
mov dx,str2
int 21h
jnc d3a ;if no error
cmp ax,2
if ne jmp err1 ;if not file-not-found
call hyphens
mov dx,offset fil
call print
mov dx,str2
call print
mov dx,offset msg3+4;' not found.'
call print
mov ah,3eh ;close other file
mov bx,si
int 21h
if c jmp err
ret
d3a: mov bx,ax
mov word bufno,0
mov word errcnt,0
; Loop for comparing. si, bx = file handles.
d4: mov cx,buflen ;read from file 1
mov dx,offset buf
xchg bx,si
mov ah,3fh
int 21h
if c jmp err ;if error
mov word len1,ax
push bx
mov bx,si
mov si,dx
add dx,cx ;read from file 2
mov ah,3fh
int 21h
if c jmp err
mov word len2,ax
push bx
mov di,dx
cmp ax,len1
jle d4z ;find minimum length
mov ax,len1
d4z: cmp ax,buflen ;whether this is the last
pushf
; Begin loop over mini-buffers
d5: mov cx,256
cmp ax,cx
jae d5a
mov cx,ax
d5a: sub ax,cx
push ax
; Do comparison.
d6: repz cmpsb
je d11 ;if buffers equal
; Print error message.
push cx
push di
cmp word errcnt,0
jne d7 ;if not the first error
mov dx,offset hdr ;print header
call print
d7: inc word errcnt
mov di,offset lyne
mov dx,di
mov ax,bufno
cmp ah,0
je d8 ;if not a huge file
push ax
mov al,ah
call hex
stosw
pop ax
d8: call hex
stosw
mov ax,si
sub ax,offset buf+1
call hex
stosw
pop bx ;old di
mov al,[si-1] ;convert data bytes to hex
mov di,offset lyne+6
call dumpbyte
mov al,[bx-1]
call dumpbyte
; Trim spaces from input line.
d9: dec di
cmp byte [di],' '
je d9 ;if space
inc di
mov ax,CR+256*LF
stosw
mov al,0
stosb
mov di,bx
call print ;print the line
pop cx
mov ax,errcnt
cmp ax,maxerrs
jb d10 ;if within limits
mov dx,offset atleast
call print
pop ax
popf
pop bx
pop si
jmp short d14
d10: or cx,cx
jnz d6 ;if more comparisons to do
d11: inc word bufno ;end mini-buffer
pop ax
or ax,ax
if nz jmp d5 ;if more in this buffer
popf
pop bx ;get file handles
pop si
if e jmp d4 ;if not eof yet
mov ax,len2
sub ax,len1
mov cl,'2'
jg d12 ;if excess bytes on file 2
je d14 ;if exact match
dec cx
xchg bx,si
neg ax
; Excess bytes on some file.
d12: mov byte xs+26,cl
mov len1,ax
mov cx,buflen
mov dx,offset buf
d13: mov ah,3fh ;read excess bytes
int 21h
jc err
add len1,ax
cmp ax,cx
je d13 ;if more to go
mov al,len1+1 ;form and print excess-bytes message
call hex
mov xs,ax
mov al,len1
call hex
mov xs+2,ax
push bx
mov dx,offset xs
call print
pop bx
inc word errcnt
; Close files and print error count.
d14: mov ah,3eh ;close file
int 21h
jc err
mov ah,3eh
xchg bx,si
int 21h
jc err
mov dx,okmsg ;get OK-message address
mov ax,errcnt
or ax,ax
jz d17 ;if no errors
mov bx,10
xor cx,cx
d15: xor dx,dx ;convert to decimal
div bx
add dl,'0'
push dx
inc cx
or ax,ax
jnz d15 ;if more digits
mov ah,2
d16: pop dx ;print the number
int 21h
loop d16
mov dx,offset nerrs
; Common ending routine.
d17: jmp short print ;call print and return
; Process errors.